package server;

import classes.*;
import dbclasses.BookingDB;
import dbclasses.CustomerDB;
import dbclasses.Dologin;
import dbclasses.Doselect;
import dbclasses.InvoiceDB;
import interfaces.Services;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.sql.Date;
import java.util.List;
import javax.swing.JOptionPane;


/**
 * The server class which implements all the methods in the Services interface
 * @author keaneb1
 */
public class Racappsrv implements Services{
    
    /**
     * This is the main server method which creates the remote registry object for responding to remote requests from clients.
     * @param args
     * @throws RemoteException
     */
    public static void main(String[] args) throws RemoteException{
        //the port used by RMI communication
        int port = 1099;
        
        //create a remote object registry that accepts calls on the specified port. 
        Registry registry = LocateRegistry.createRegistry(port);
        
        try{
            Racappsrv racsrv = new Racappsrv();
            
            /* export the remote object with Java Remote Method Protocol (JRMP) and obtaining a stub that communicates to the remote object. 
             * All the methods in the Services interface are implemented
             */
            Services stub = (Services) UnicastRemoteObject.exportObject(racsrv, port);
        
            /*The following code in the server obtains a stub for a registry on the local host
            * and default registry port and then uses the registry stub to bind the name "RacappSrv" 
            * to the remote object's stub in that registry: 
            */
            registry = LocateRegistry.getRegistry();
            registry.bind("RacappSrv", stub);
        }
        catch(RemoteException | AlreadyBoundException ex){
            //let me know why you can't create a new remote registry object
            JOptionPane.showMessageDialog(null, "Problem creating RMI object " +ex.getMessage());
        }
    }

   /**
    * Method to override the doLogin method of the Services interface
    * @param username entered by the user during login 
    * @param password entered by the user during login 
    * @return a user object if it is matched by the username and password entered
    * @throws RemoteException
    */
   @Override
    public User doLogin(String username, String password) throws RemoteException{
        return Dologin.login(username, password);
    }
   
   /**
    * Method to override the getUniqueLocations method of the Services interface
    * @return the list of unique locations from the database
    * @throws RemoteException
    */
   @Override
    public List<String> getUniqueLocations() throws RemoteException {
        return Doselect.getUniqueLocations();
    }

    /**
     * Method to override the getCarsByLocationCategory method of the Services interface
     * @param location selected by the user in the GUI
     * @param category selected by the user at the GUI
     * @param fromDate entered by the user at the GUI
     * @param toDate entered by the user at the GUI
     * @return the list of available cars for the above conditions.
     * @throws RemoteException
     */
    @Override
    public List<Car> getCarsByLocationCategory(String location, String category, Date fromDate, Date toDate) throws RemoteException {
        return Doselect.getCarsByLocationCategory(location, category, fromDate, toDate);
    }

    /**
     * Method to override the getCategories method of the Services interface
     * @return the list containing the unique categories from the database
     * @throws RemoteException
     */
    @Override
    public List<String> getCategories() throws RemoteException {
        return Doselect.getCategories();
    }

    /**
     * Method to override the getPricePerCategory method of the Services interface
     * @param category the selected category to check the price for
     * @return the daily rate value for that category from the database
     * @throws RemoteException
     */
    @Override
    public double getPricePerCategory(String category) throws RemoteException {
        return Doselect.getPricePerCategory(category);
    }

    /**
     * Method to override the getCustomers method of the Services interface
     * @param searchString a string of numbers to narrow the customer list
     * @return the list of customers based on the search string
     * @throws RemoteException
     */
    @Override
    public List<Customer> getCustomers(String searchString) throws RemoteException {
        return Doselect.getCustomers(searchString);
    }

    /**
     * Method to override the insertNewBooking method of the Services interface
     * @param newBooking the booking object to be inserted into the database
     * @return true if the insert was a success, otherwise return false
     * @throws RemoteException
     */
    @Override
    public boolean insertNewBooking(Booking newBooking) throws RemoteException {
        return BookingDB.insertNewBooking(newBooking);
    }

    /**
     * Method to override the insertNewCard method of the Services interface
     * @param card the card object to be inserted into the database
     * @return true if the insert was a success, otherwise return false
     * @throws RemoteException
     */
    @Override
    public boolean insertNewCard(Card card) throws RemoteException {
       return CustomerDB.insertCard(card);
    }

    /**
     * Method to override the insertNewCustomer method of the Services interface
     * @param newCustomer the customer object to be inserted into the database
     * @return true if the insert was a success, otherwise return false
     * @throws RemoteException
     */
    @Override
    public boolean insertNewCustomer(Customer newCustomer) throws RemoteException {
        return CustomerDB.insertCustomer(newCustomer);
    }

    /**
     * Method to override the getBookingId method of the Services interface
     * @param newBooking the booking which is to be queried
     * @return the booking id number
     * @throws RemoteException
     */
    @Override
    public int getBookingId(Booking newBooking) throws RemoteException {
        return BookingDB.getBookingId(newBooking);
    }

    /**
     * Method to override the insertNewInvoice method of the Services interface
     * @param invc the invoice object to be saved to the database.
     * @return the boolean value of success if transaction completed or failed.
     * @throws RemoteException
     */
    @Override
    public boolean insertNewInvoice(Invoice invc) throws RemoteException {
        return InvoiceDB.insertNewInvoice(invc);
    }
}
